﻿using Furion;
using Furion.DatabaseAccessor;
using Furion.DataEncryption;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.Core;
using Furion.Core.Entities.Enums;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Security.Claims;
using Furion.DatabaseAccessor.Extensions;
using System.Drawing;
using Furion.DistributedIDGenerator;
using Microsoft.Extensions.Caching.Memory;

namespace Furion.Application
{
    [AppAuthorize, ApiDescriptionSettings("System", Name = "Org", Order = 2, Tag = "部门")]
    public  class OrgService : IDynamicApiController
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IRepository<Furion.Core.Org> _orgRepository;
        private readonly IRepository<User> _userRepository;
        private readonly IAuthorizationManager _authorizationManager;

       

        public OrgService(IHttpContextAccessor httpContextAccessor,
            IRepository<Furion.Core.Org> orgRepository,
            IRepository<User> useRepository,
            IAuthorizationManager authorizationManager)
        {
            _httpContextAccessor = httpContextAccessor;
            _orgRepository = orgRepository;
            _userRepository = useRepository;
            _authorizationManager = authorizationManager;
        }


        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Org_Add),HttpPost("/Org/Add"), ApiDescriptionSettings(Name = "Add")]
        public async Task AddAsync([Required] OrgAddInput input)
        {
            var addInput = input.Adapt<Org>();
            addInput.CreatedTime = DateTime.Now;
            addInput.UpdatedTime = DateTime.Now;
            var entryEntity = await _orgRepository.InsertNowAsync(addInput);
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Org_Edit), HttpPost("/Org/Edit"), ApiDescriptionSettings(Name = "Edit")]
        public async Task EditAsync([Required] OrgEditInput input)
        {
            var editInput = input.Adapt<Org>();
            editInput.UpdatedTime = DateTime.Now;

            await _orgRepository.UpdateAsync(editInput);
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Org_List), HttpPost("/Org/PageList"), ApiDescriptionSettings(Name = "PageList")]
        public async Task<List<OrgTree>> PageListAsync()
        {
            var items = await _orgRepository.AsQueryable().ToListAsync();
            var trees = items.Where(a => a.ParentId == 0).Adapt<List<OrgTree>>();
            foreach(var item in trees)
            {
                item.children = GetChilds(items, item.Id);
            }
            return trees;
        }

        /// <summary>
        /// 子级菜单
        /// </summary>
        /// <param name="DataSource"></param>
        /// <param name="ParentId"></param>
        /// <returns></returns>
        [ApiDescriptionSettings(false)]
        public List<OrgTree> GetChilds(List<Org> DataSource, int ParentId)
        {
            var items = DataSource.Where(a => a.ParentId == ParentId).ToList().Adapt<List<OrgTree>>();
            foreach (var item in items)
            {
                item.children = GetChilds(DataSource, item.Id);
            }
            return items;
        }


        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Org_Delete), HttpPost("/Org/Delete"), ApiDescriptionSettings(Name = "Delete")]
        public async Task DeleteRange(OrgDeleteRangeInput input)
        {
            var items = await _orgRepository.DetachedEntities.Where(u => input.Ids.Contains(u.Id)).ToListAsync();
            if(items.Count>0)
            {
                await _orgRepository.DeleteNowAsync(items);
            }
            
        }

    }
}
